/**
 * Created by PanJiaChen on 16/11/18.
 */

/**
 * 时间日期格式化
 * @param format
 * @returns {*}
 */
export const dateFormat = function(dateObj, format) {
  const date = {
    'M+': dateObj.getMonth() + 1,
    'd+': dateObj.getDate(),
    'h+': dateObj.getHours(),
    'm+': dateObj.getMinutes(),
    's+': dateObj.getSeconds(),
    'q+': Math.floor((dateObj.getMonth() + 3) / 3),
    'S+': dateObj.getMilliseconds()
  }
  if (/(y+)/i.test(format)) {
    format = format.replace(
      RegExp.$1,
      (dateObj.getFullYear() + '').substr(4 - RegExp.$1.length)
    )
  }
  for (const k in date) {
    if (new RegExp('(' + k + ')').test(format)) {
      format = format.replace(
        RegExp.$1,
        RegExp.$1.length === 1
          ? date[k]
          : ('00' + date[k]).substr(('' + date[k]).length)
      )
    }
  }
  return format
}
/**
 * 格式化时间 YYYY-MM-DD hh:mm:ss week
 * @param {String} fromat 时间的格式
 * @param {time} time 一个可以被new Date装换为时间的值
 */

export function formatDate(format = 'YYYY-MM-DD', time) {
  const date = time ? new Date(time) : new Date()
  const flags = {
    YYYY: date.getFullYear,
    MM() {
      return date.getMonth() + 1
    },
    DD: date.getDate,
    hh: date.getHours,
    mm: date.getMinutes,
    ss: date.getSeconds,
    week() {
      const week = ['日', '一', '二', '三', '四', '五', '六']
      return week[date.getDay()]
    }
  }
  return format.replace(/Y{4}|M{2}|D{2}|h{2}|m{2}|s{2}|week/g, key => {
    const value = flags[key].call(date)
    return typeof value !== 'number' || value > 9 ? value : '0' + value
  })
}

/**
 * Parse the time to string
 * @param {(Object|string|number)} time
 * @param {string} cFormat
 * @returns {string | null}
 */
export function parseTime(time, cFormat) {
  if (arguments.length === 0 || !time) {
    return null
  }
  const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'
  let date
  if (typeof time === 'object') {
    date = time
  } else {
    if (typeof time === 'string') {
      if (/^[0-9]+$/.test(time)) {
        // support "1548221490638"
        time = parseInt(time)
      } else {
        // support safari
        // https://stackoverflow.com/questions/4310953/invalid-date-in-safari
        time = time.replace(new RegExp(/-/gm), '/')
      }
    }

    if (typeof time === 'number' && time.toString().length === 10) {
      time = time * 1000
    }
    date = new Date(time)
  }
  const formatObj = {
    y: date.getFullYear(),
    m: date.getMonth() + 1,
    d: date.getDate(),
    h: date.getHours(),
    i: date.getMinutes(),
    s: date.getSeconds(),
    a: date.getDay()
  }
  const time_str = format.replace(/{([ymdhisa])+}/g, (result, key) => {
    const value = formatObj[key]
    // Note: getDay() returns 0 on Sunday
    if (key === 'a') {
      return ['日', '一', '二', '三', '四', '五', '六'][value]
    }
    return value.toString().padStart(2, '0')
  })
  return time_str
}

/**
 * @param {number} time
 * @param {string} option
 * @returns {string}
 */
export function formatTime(time, option) {
  if (('' + time).length === 10) {
    time = parseInt(time) * 1000
  } else {
    time = +time
  }
  const d = new Date(time)
  const now = Date.now()

  const diff = (now - d) / 1000

  if (diff < 30) {
    return '刚刚'
  } else if (diff < 3600) {
    // less 1 hour
    return Math.ceil(diff / 60) + '分钟前'
  } else if (diff < 3600 * 24) {
    return Math.ceil(diff / 3600) + '小时前'
  } else if (diff < 3600 * 24 * 2) {
    return '1天前'
  }
  if (option) {
    return parseTime(time, option)
  } else {
    return (
      d.getMonth() +
      1 +
      '月' +
      d.getDate() +
      '日' +
      d.getHours() +
      '时' +
      d.getMinutes() +
      '分'
    )
  }
}

/**
 * @param {string} url
 * @returns {Object}
 */
export function param2Obj(url) {
  const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ')
  if (!search) {
    return {}
  }
  const obj = {}
  const searchArr = search.split('&')
  searchArr.forEach(v => {
    const index = v.indexOf('=')
    if (index !== -1) {
      const name = v.substring(0, index)
      const val = v.substring(index + 1, v.length)
      obj[name] = val
    }
  })
  return obj
}

/**
 * 判断param是否为空或空字符串
 * @param {} param
 */
const isNullOrEmpty = param => {
  if (param == null || param === undefined || param === '') {
    return true
  }
  return false
}

/**
 * 遍历param，判断是否为空。若全非空返回true
 * @param {*} param json对象
 * @param {*} except 数组：不判断此数组中的元素是否为空
 */
const traversalEmptyValidate = (param, except) => {
  if (!isNullOrEmpty(param)) {
    // 获取键名数组
    let keys = Object.keys(param)
    // 是否非空的标识
    let flag = true
    if (!isNullOrEmpty(except) && except.length > 0) {
      // except非空时执行
      keys.forEach(el => {
        if (
          isNullOrEmpty(param[el]) &&
          !except.find((value, index, arr) => {
            // 判断当前遍历到的键名是否存在于except数组中
            return value === el
          })
        ) {
          // 判断条件：param[el]为空或空字符串，并且键名el不在except数组中，则此项为空，返回false
          flag = false
          return false
        }
      })
    } else {
      // except数组为空时执行
      keys.forEach(el => {
        if (isNullOrEmpty(param[el])) {
          flag = false
          return false
        }
      })
    }
    if (!flag) {
      return false
    }
    return true
  }
  return false
}

/**
 *  验证重复元素，有重复返回true；否则返回false
 */
const isRepeat = arr => {
  var hash = {}
  for (var i in arr) {
    if (hash[arr[i]]) {
      return true
    }
    hash[arr[i]] = true
  }
  return false
}

/**
 * 将一个数组分成几个同等长度的数组
 * array[分割的原数组]
 * size[每个子数组的长度]
 */

const sliceArray = (array, size) => {
  var result = []
  for (var x = 0; x < Math.ceil(array.length / size); x++) {
    var start = x * size
    var end = start + size
    result.push({ id: 'sliceTab_' + x, data: array.slice(start, end) })
  }
  return result
}

/**
 * 判断某个原生DOM元素是否不在屏幕可见区内
 * @param {*} el 原生DOM元素
 */
const isElementNotInViewport = function(el) {
  let rect = el.getBoundingClientRect()
  return (
    rect.top >= (window.innerHeight || document.documentElement.clientHeight) ||
    rect.bottom <= 0
  )
}
/**
 * @method getChildTree 获取反显需要的列表
 * @param {Array} codes 渠道列表的code
 */
export function getChildTree(codes, getChildTree, eachHandle) {
  return Promise.all(codes.map(code => getChildTree(code))).then(res => {
    let arr = new Array()
    res
      .map(item => item.data.map(eachHandle))
      .reduce((array, resItem, index) => {
        if (index === res.length - 1) {
          resItem.map(item => ({ ...item, leaf: true }))
        }
        if (index === 0) {
          arr = resItem
        } else {
          //console.log(arr, codes[index], codes)
          const res = array.find(item => item.key == codes[index])
          if (res) {
            res.children = resItem
          } else {
            throw Error('codes Error')
          }
        }
        return resItem
      }, arr)
    return [arr, res]
  })
}
export function downloadFile(url) {
  let a = window.document.createElement('a')
  a.href =
    url +
    (url.indexOf('?') === -1 ? '?' : '&') +
    'response-content-type=application/octet-stream'
  a.download = true
  a.click()
  a = null
}
export {
  isNullOrEmpty,
  traversalEmptyValidate,
  isRepeat,
  sliceArray,
  isElementNotInViewport
}
